home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / decomp / call_ovqp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-12-18  |  7.4 KB  |  368 lines

  1. # include    <errors.h>
  2. # include    <ingres.h>
  3. # include    <aux.h>
  4. # include    <opsys.h>
  5. # include    <access.h>
  6. # include    <tree.h>
  7. # include    <symbol.h>
  8. # include    "globs.h"
  9. # include    <sccs.h>
  10.  
  11. SCCSID(@(#)call_ovqp.c    8.6    12/18/85)
  12.  
  13.  
  14. /*
  15. ** CALL_OVQP -- Routines which interface to the One Variable Query Processor.
  16. **
  17. **    This file contains the routines associated with sending queries
  18. **    and receiving results from OVQP. The interface to these routines is
  19. **    still messy. Call_ovqp is given the query, mode, and result relation
  20. **    as parameters and gets the source relation, and two flags
  21. **    (De.de_newq, De.de_newr) as globals. The routines include:
  22. **
  23. **    Call_ovqp -- Sends a One-var query to ovqp and flushes the pipe.
  24. **
  25. **    Readresult -- Reads the result from a one-var query.
  26. **
  27. **    Endovqp    -- Informs ovqp that the query is over. Helps to synchronize
  28. **            the batch file (if any).
  29. **
  30. **    Trace Flags:
  31. **        61
  32. */
  33. /*
  34. ** Call_ovqp -- send query down pipe to ovqp and flush pipe.
  35. **    Inputs are:
  36. **        mode        retrieve, append, etc.
  37. **        resultnum    result relation id
  38. **        tree        the query
  39. **        De.de_sourcevar    (global) if >= 0 then source var
  40. **        De.de_newq        send NEWQ symbol
  41. **        De.de_newr        send NEWR symbol
  42. */
  43.  
  44. call_ovqp(tree, mode, resultnum)
  45. register QTREE     *tree;
  46. int        mode;
  47. int        resultnum;
  48. {
  49.     register int    i;
  50.     char        *rangename();
  51.     extern int    derror();
  52.     extern bool    Batchupd;
  53.     extern DESC    Inddes;
  54.     int        ovqpbuf[1+LBUFSIZE/sizeof(int)];
  55.     DESC        *readopen();
  56.     extern DESC    *specopen();
  57.     extern char    *rnum_convert();
  58.  
  59.  
  60. #    ifdef xDTR1
  61.     if (tTf(61, -1))
  62.     {
  63.         if (tTf(61, 0))
  64.             printf("CALL_OVQP-\n");
  65.         if (tTf(61, 1))
  66.         {
  67.             if (De.de_newq)
  68.             {
  69.                 printf("new query to ovqp\n");
  70.                 treepr(tree);
  71.             }
  72.             else
  73.                 printf("query same as previous\n");
  74.         }
  75.         if (tTf(61, 2))
  76.         {
  77.             printf("De.de_sourcevar=%d\t", De.de_sourcevar);
  78.             if (De.de_sourcevar >= 0)
  79.                 printf("relid=%s\t", rangename(De.de_sourcevar));
  80.             if (resultnum >= 0)
  81.                 printf("De.ov_resultname=%s", rnum_convert(resultnum));
  82.             if (tree->sym.value.sym_root.rootuser)
  83.                 printf(", userqry");
  84.             printf("\n");
  85.         }
  86.     }
  87. #    endif
  88.  
  89.  
  90.  
  91.     /* assign mode of this query */
  92.     De.de_qmode = mode;
  93.  
  94.     if (De.de_newr)
  95.     {
  96.         De.de_newr = FALSE;
  97.     }
  98.  
  99.     if (resultnum >= 0)
  100.     {
  101.         De.ov_result = specopen(resultnum);
  102.     }
  103.     else
  104.         De.ov_result = NULL;
  105.  
  106.     if (De.de_sourcevar >= 0)
  107.         De.ov_source = readopen(De.de_sourcevar);
  108.     else
  109.         De.ov_source = NULL;
  110.  
  111.     /* assume this will be direct update */
  112.     De.ov_userqry = De.de_buflag = FALSE;
  113.  
  114.     if (tree->sym.value.sym_root.rootuser)
  115.     {
  116.         De.ov_userqry = TRUE;
  117.         /* handle batch file */
  118.         if (De.ov_result && De.de_qmode != mdRETR)
  119.         {
  120.             if (Batchupd || De.ov_result->reldum.relindxd > 0)
  121.             {
  122.                 if (De.ov_bopen == 0)
  123.                 {
  124.                     if (De.ov_result->reldum.relindxd > 0)
  125.                         opencatalog("indexes", OR_READ);
  126.                     if (i = openbatch(De.ov_result, &Inddes, De.de_qmode))
  127.                         syserr("call_ovqp:opn batch %d", i);
  128.                     De.ov_bopen = TRUE;
  129.                 }
  130.                 De.de_buflag = TRUE;
  131.             }
  132.         }
  133.     }
  134.  
  135.     /*  now write the query list itself  */
  136.     if (De.de_newq)
  137.     {
  138.         De.ov_ovqpbuf = (char *)ovqpbuf;
  139.         initbuf(De.ov_ovqpbuf, LBUFSIZE, LISTFULL, derror);
  140.         De.de_qvptr = 0;
  141.         De.ov_alist = De.ov_bylist = De.ov_qlist = De.ov_tlist = NULL;
  142.         De.ov_targvc = tree->sym.value.sym_root.lvarc;
  143.         De.ov_qualvc = bitcnt(tree->sym.value.sym_root.rvarm);
  144.         De.ov_agcount = 0;
  145.  
  146.         if (tree->sym.type == AGHEAD)
  147.         {
  148.             De.ov_alist = &De.de_qvect[0];
  149.             if (tree->left->sym.type == BYHEAD)
  150.             {
  151.                 mklist(tree->left->right);
  152.                 ovqpnod(tree->left);    /* BYHEAD node */
  153.                 De.ov_bylist = &De.de_qvect[De.de_qvptr];
  154.                 mklist(tree->left->left);
  155.             }
  156.             else
  157.                 mklist(tree->left);
  158.         }
  159.         else
  160.         {
  161.             if (tree->left->sym.type != TREE)
  162.             {
  163.                 De.ov_tlist = &De.de_qvect[0];
  164.                 mklist(tree->left);
  165.             }
  166.         }
  167.  
  168.         /* now for the qualification */
  169.         ovqpnod(tree);    /* ROOT node */
  170.  
  171.         if (tree->right->sym.type != QLEND)
  172.         {
  173.             De.ov_qlist = &De.de_qvect[De.de_qvptr];
  174.             mklist(tree->right);
  175.         }
  176.         ovqpnod(De.de_qle);    /* QLEND node */
  177.     }
  178.  
  179.     /* Now call ovqp */
  180.     if (strategy())
  181.     {
  182.         i = scan();    /* scan the relation */
  183.     }
  184.     else
  185.         i = EMPTY;
  186.  
  187.     /* return result of query */
  188.     return (i == NONEMPTY);    /* TRUE if tuple satisfied */
  189. }
  190. /*
  191. ** Endovqp -- Inform ovqp that processing is complete. "Ack" indicates
  192. **    whether to wait for an acknowledgement from ovqp. The overall
  193. **    mode of the query is sent followed by an EXIT command.
  194. **
  195. **    Ovqp decides whether to use batch update or not. If ack == ACK
  196. **    then endovqp will read a RETVAL symbol from ovqp and return
  197. **    a token which specifies whether to call the update processor or not.
  198. */
  199.  
  200. endovqp(ack)
  201. int    ack;
  202. {
  203.     register int    i;
  204.  
  205.     if (ack != RUBACK)
  206.     {
  207.         if (Equel && De.de_qry_mode == mdRETTERM)
  208.             equeleol(EXIT);    /* signal end of retrieve to equel process */
  209.     }
  210.  
  211.     i = NOUPDATE;
  212.  
  213.     if (ack == ACK)
  214.     {
  215.         if (De.ov_bopen)
  216.         {
  217.             closebatch();
  218.             De.ov_bopen = FALSE;
  219.             i = UPDATE;
  220.         }
  221.     }
  222.     else
  223.     {
  224.         if (De.ov_bopen)
  225.         {
  226.             rmbatch();
  227.             De.ov_bopen = FALSE;
  228.         }
  229.     }
  230.  
  231.     closecatalog(FALSE);
  232.  
  233.     return (i);
  234. }
  235. /*
  236. **    Add node q to ovqp's list
  237. */
  238.  
  239. ovqpnod(q)
  240. register QTREE    *q;
  241. {
  242.     register SYMBOL    *s;
  243.     extern QTREE    *ckvar();
  244.     extern char    *need();
  245.     register int    i;
  246.  
  247.     s = &q->sym;
  248.  
  249.     /* VAR nodes must be specially processed */
  250.     if (s->type == VAR)
  251.     {
  252.         /* locate currently active VAR */
  253.         q = ckvar(q);
  254.  
  255.         /* Allocate an ovqp var node for the VAR */
  256.         s = (SYMBOL *) need(De.ov_ovqpbuf, SYM_HDR_SIZ + sizeof s->value.sym_var);
  257.         s->len = sizeof s->value.sym_var;
  258.         s->value.sym_var.attno = q->sym.value.sym_var.attno;
  259.         s->value.sym_var.varfrmt = q->sym.value.sym_var.varfrmt;
  260.         s->value.sym_var.varfrml = q->sym.value.sym_var.varfrml;
  261.         s->value.sym_var.varstr = q->sym.value.sym_var.varstr;
  262.  
  263.         /* If VAR has been substituted for, get value */
  264.         if (q->sym.value.sym_var.valptr)
  265.         {
  266.             /* This is a substituted variable */
  267.             if (q->sym.value.sym_var.varno == De.de_sourcevar)
  268.                 syserr("ovqpnod:bd sub %d,%d", q->sym.value.sym_var.varno, De.de_sourcevar);
  269.  
  270.             s->type = S_VAR;
  271.             s->value.sym_var.valptr = q->sym.value.sym_var.valptr;
  272.         }
  273.         else
  274.         {
  275.             /* Var for one variable query */
  276.             if (q->sym.value.sym_var.varno != De.de_sourcevar)
  277.                 syserr("ovqpnod:src var %d,%d", q->sym.value.sym_var.varno, De.de_sourcevar);
  278.             s->type = VAR;
  279.             i = q->sym.value.sym_var.attno;
  280.             if (i != 0)
  281.                 s->value.sym_var.valptr = (ANYTYPE *) (De.ov_intup + De.ov_source->reloff[i]);
  282.             else
  283.                 s->value.sym_var.valptr = (ANYTYPE *) &De.ov_intid;
  284.         }
  285.     }
  286.     if (s->type == AOP)
  287.         De.ov_agcount++;
  288.  
  289.     /* add symbol to list */
  290.     if (De.de_qvptr > MAXNODES - 1)
  291.         ov_err(NODOVFLOW);
  292.     De.de_qvect[De.de_qvptr++] = s;
  293. }
  294. /*
  295. **  READAGG_RESULT
  296. */
  297.  
  298. readagg_result(result)
  299. QTREE    *result[];
  300. {
  301.     register QTREE    **r, *aop;
  302.     register int    i;
  303.  
  304.     De.ov_tend = De.ov_outtup;
  305.     r = result;
  306.  
  307.     while (aop = *r++)
  308.     {
  309.         i = aop->sym.len & I1MASK;
  310.  
  311.         if (aop->sym.type == CHAR)
  312.             pad(De.ov_tend, i);
  313.  
  314.         bmove(De.ov_tend, (char *)&aop->sym.value, i);
  315.  
  316.         De.ov_tend += i;
  317. #        ifdef xDTR1
  318.         if (tTf(61, 3))
  319.             nodepr(aop);
  320. #        endif
  321.     }
  322. }
  323.  
  324.  
  325. ov_err(code)
  326. int    code;
  327. {
  328.     derror(code);
  329. }
  330.  
  331.  
  332. DESC *
  333. openindex(name)
  334. char    *name;
  335. {
  336.     register DESC    *d;
  337.     register int    varno;
  338.     DESC        *readopen();
  339.  
  340.     varno = SECINDVAR;
  341.     De.de_rangev[varno].relnum = rnum_findadd(name);
  342.     d = readopen(varno);
  343.     return (d);
  344. }
  345. /*
  346. **    Use "closer()" for closing relations. See
  347. **    desc_close in openrs.c for details.
  348. */
  349. extern int    closer();
  350. int        (*Des_closefunc)()    = closer;
  351.  
  352. init_decomp()
  353. {
  354.     static struct accbuf    xtrabufs[12];
  355.  
  356.     set_so_buf();
  357.     acc_addbuf(xtrabufs, 12);
  358. }
  359.  
  360.  
  361. startdecomp()
  362. {
  363.     /* called at the start of each user query */
  364.     initrange();
  365.     rnum_init();
  366.     startovqp();
  367. }
  368.